<template>
  <div class="similar-logic">
    <div class="list-wrap tag-scrollbar" @drop="copyDrop($event)" @dragover="allowDrag($event)">
      <div class="ul">
        <template v-if="derivedTagData.tagList.length">
          <div
            class="logical"
            :class="{ 'logical-or': derivedTagData.logicalOperation === 'or' }"
            v-if="derivedTagData.tagList.length > 1"
          >
            <el-form-item prop="logicalOperation">
              <el-select
                v-model="derivedTagData.logicalOperation"
                @click.native="toggleOperation(-1)"
                disabled
                popper-class="factory-select"
                class="default"
              >
                <el-option label="且" value="and"></el-option>
                <el-option label="或" value="or"></el-option>
              </el-select>
            </el-form-item>
          </div>
          <div v-for="(item, index) in derivedTagData.tagList" :key="index" class="ul-wrap">
            <!-- 没有下级 -->
            <template v-if="!item.tagList">
              <div class="list-item" :level="1" :tagId="item.tagId" :index="index">
                <el-row :gutter="8">
                  <el-col :span="8">
                    <div
                      class="item"
                      :class="{ 'lost-item': !item.tagId }"
                      align="center"
                      :draggable="!!item.tagId"
                      @dragstart="copyDrag($event, item, index)"
                    >
                      {{ item.tagNm }}
                    </div>
                  </el-col>
                  <template v-if="item.tagId">
                    <el-col :span="4" align="center">
                      <div class="item">
                        <el-form-item
                          :prop="formProp + '.tagList.' + index + '.operationType'"
                          :rules="[
                            {
                              required: true,
                              message: '运算符不能为空',
                              trigger: 'change'
                            }
                          ]"
                        >
                          <el-select v-model="item.operationType" @change="changeType($event, item)">
                            <el-option label="---" value=""></el-option>
                            <el-option
                              v-for="opera in operatorType('type' + item.valueType)"
                              :key="opera.value"
                              :label="opera.key"
                              :value="opera.value"
                            ></el-option>
                          </el-select>
                        </el-form-item>
                      </div>
                    </el-col>
                    <el-col :span="12">
                      <div class="item">
                        <el-form-item
                          :prop="formProp + '.tagList.' + index + '.operationValue'"
                          :rules="[
                            {
                              required: true,
                              message: '值不能为空',
                              trigger: ['blur', 'change']
                            }
                          ]"
                        >
                          <factory-content-item :config="item"></factory-content-item>
                        </el-form-item>
                      </div>
                    </el-col>
                  </template>
                  <el-col :span="16" v-else>
                    <div class="item lost-item">标签被更改或删除</div>
                  </el-col>
                </el-row>
                <el-button
                  type="primary"
                  size="mini"
                  icon="el-icon-close"
                  :class="{ 'lost-item': !item.tagId }"
                  circle
                  @click="deleteItem(index)"
                ></el-button>
              </div>
            </template>
            <template v-else>
              <div class="ol" :class="{ space: item.tagList.length > 1 }">
                <div class="logical" :class="{ 'logical-or': item.logicalOperation === 'or' }">
                  <el-form-item :prop="formProp + '.tagList.' + index + '.logicalOperation'">
                    <el-select
                      v-model="item.logicalOperation"
                      @click.native="toggleOperation(index)"
                      :level="index"
                      popper-class="factory-select"
                      disabled
                      class="default"
                    >
                      <el-option label="且" value="and"></el-option>
                      <el-option label="或" value="or"></el-option>
                    </el-select>
                  </el-form-item>
                </div>
                <div v-for="(child, index2) in item.tagList" :key="index2">
                  <!-- 没有第三层 -->
                  <template v-if="!child.tagList">
                    <div class="list-item" :level="2" :tagId="child.tagId" :index="index + '-' + index2">
                      <el-row :gutter="8">
                        <el-col :span="8">
                          <div
                            class="item"
                            :class="{ 'lost-item': !child.tagId }"
                            align="center"
                            :draggable="!!child.tagId"
                            @dragstart="copyDrag($event, child, index, index2)"
                          >
                            {{ child.tagNm }}
                          </div>
                        </el-col>
                        <template v-if="child.tagId">
                          <el-col :span="4" align="center">
                            <div class="item">
                              <el-form-item
                                :prop="formProp + '.tagList.' + index + '.tagList.' + index2 + '.operationType'"
                                :rules="[
                                  {
                                    required: true,
                                    message: '运算符不能为空',
                                    trigger: 'change'
                                  }
                                ]"
                              >
                                <el-select v-model="child.operationType" @change="changeType($event, child)">
                                  <el-option label="---" value=""></el-option>
                                  <el-option
                                    v-for="opera in operatorType('type' + child.valueType)"
                                    :key="opera.value"
                                    :label="opera.key"
                                    :value="opera.value"
                                  ></el-option>
                                </el-select>
                              </el-form-item>
                            </div>
                          </el-col>
                          <el-col :span="12">
                            <div class="item">
                              <el-form-item
                                :prop="formProp + '.tagList.' + index + '.tagList.' + index2 + '.operationValue'"
                                :rules="[
                                  {
                                    required: true,
                                    message: '值不能为空',
                                    trigger: ['blur', 'change']
                                  }
                                ]"
                              >
                                <factory-content-item :config="child"></factory-content-item>
                              </el-form-item>
                            </div>
                          </el-col>
                        </template>
                        <el-col :span="16" v-else>
                          <div class="item lost-item">标签被更改或删除</div>
                        </el-col>
                      </el-row>
                      <el-button
                        type="primary"
                        size="mini"
                        icon="el-icon-close"
                        circle
                        :class="{ 'lost-item': !child.tagId }"
                        @click="deleteItem(index, index2)"
                      ></el-button>
                    </div>
                  </template>
                  <div class="ol space" v-else>
                    <!-- 第三层的逻辑符号 -->
                    <div class="logical" :class="{ 'logical-or': child.logicalOperation === 'or' }">
                      <el-form-item :prop="formProp + '.tagList.' + index + '.tagList.' + index2 + '.logicalOperation'">
                        <el-select
                          v-model="child.logicalOperation"
                          @click.native="toggleOperation(index, index2)"
                          :level="index + '-' + index2"
                          popper-class="factory-select"
                          disabled
                          class="default"
                        >
                          <el-option label="且" value="and"></el-option>
                          <el-option label="或" value="or"></el-option>
                        </el-select>
                      </el-form-item>
                    </div>
                    <div v-for="(third, index3) in child.tagList" :key="index3">
                      <div
                        class="list-item"
                        :level="3"
                        :tagId="third.tagId"
                        :index="index + '-' + index2 + '-' + index3"
                      >
                        <el-row :gutter="8">
                          <el-col :span="8">
                            <div
                              class="item"
                              :class="{ 'lost-item': !third.tagId }"
                              align="center"
                              :draggable="!!third.tagId"
                              @dragstart="copyDrag($event, third, index, index2, index3)"
                            >
                              {{ third.tagNm }}
                            </div>
                          </el-col>
                          <template v-if="third.tagId">
                            <el-col :span="4" align="center">
                              <div class="item">
                                <el-form-item
                                  :prop="
                                    formProp +
                                      '.tagList.' +
                                      index +
                                      '.tagList.' +
                                      index2 +
                                      '.tagList.' +
                                      index3 +
                                      '.operationType'
                                  "
                                  :rules="[
                                    {
                                      required: true,
                                      message: '运算符不能为空',
                                      trigger: 'change'
                                    }
                                  ]"
                                >
                                  <el-select v-model="third.operationType" @change="changeType($event, third)">
                                    <el-option label="---" value=""></el-option>
                                    <el-option
                                      v-for="opera in operatorType('type' + third.valueType)"
                                      :key="opera.value"
                                      :label="opera.key"
                                      :value="opera.value"
                                    ></el-option>
                                  </el-select>
                                </el-form-item>
                              </div>
                            </el-col>
                            <el-col :span="12">
                              <div class="item">
                                <el-form-item
                                  :prop="
                                    formProp +
                                      '.tagList.' +
                                      index +
                                      '.tagList.' +
                                      index2 +
                                      '.tagList.' +
                                      index3 +
                                      '.operationValue'
                                  "
                                  :rules="[
                                    {
                                      required: true,
                                      message: '值不能为空',
                                      trigger: ['blur', 'change']
                                    }
                                  ]"
                                >
                                  <factory-content-item :config="third"></factory-content-item>
                                </el-form-item>
                              </div>
                            </el-col>
                          </template>
                          <el-col :span="16" v-else>
                            <div class="item lost-item">标签被更改或删除</div>
                          </el-col>
                        </el-row>
                        <el-button
                          type="primary"
                          size="mini"
                          icon="el-icon-close"
                          circle
                          :class="{ 'lost-item': !third.tagId }"
                          @click="deleteItem(index, index2, index3)"
                        ></el-button>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </template>
          </div>
        </template>
        <div class="logic-info" v-else><i class="el-icon-plus"></i>请拖入标签</div>
      </div>
    </div>
  </div>
</template>

<script>
import operator from '@/views/modules/factory/operator'
import factoryContentItem from '@/views/modules/factory/factory-content-item'
export default {
  props: {
    derivedTagData: {
      type: Object,
      required: true,
      default: () => {
        return { logicalOperation: 'and', tagList: [] }
      }
    },
    formProp: {
      // 绑定form表单的prop名称
      type: String,
      required: true,
      default: 'editForm'
    }
  },
  components: {
    factoryContentItem
  },
  data() {
    return {}
  },
  methods: {
    operatorType(key) {
      return operator[key]
    },
    changeType(type, item) {
      if (item.valueType == '4' || item.valueType == '5') {
        if (type === 'a<=x<b') item.operationValue = []
        else if (type === 8 || type === 9) item.operationValue = [1, '1']
        else item.operationValue = ''
      } else if (item.valueType == '6') {
        if (type === 'a<=x<b') item.operationValue = [1, 1]
        else item.operationValue = ''
      } else if (item.valueType == '7') {
        if (type === 'a<=x<b') item.operationValue = [1.0, 1.0]
        else item.operationValue = ''
      } else {
        item.operationValue = ''
      }
    },
    toggleOperation(index, index2 = -1) {
      if (index < 0) {
        this.derivedTagData.logicalOperation = this.derivedTagData.logicalOperation === 'and' ? 'or' : 'and'
      } else {
        if (index2 < 0) {
          const operation = this.derivedTagData.tagList[index].logicalOperation
          this.derivedTagData.tagList[index].logicalOperation = operation === 'and' ? 'or' : 'and'
        } else {
          const operation = this.derivedTagData.tagList[index].tagList[index2].logicalOperation
          this.derivedTagData.tagList[index].tagList[index2].logicalOperation = operation === 'and' ? 'or' : 'and'
        }
      }
    },
    addItem(item) {
      const arg = {
        tagId: item.assetId,
        tagNm: item.assetNm,
        valueType: item.valueType,
        tagCode: item.assetCode,
        valueTypeCode: item.valueTypeCode,
        enums: item.enums,
        labTbl: item.labTbl,
        labFldMap: item.labFldMap,
        dictDatabaseType: item.dbVal,
        operationType: '',
        operationValue: '',
        isDerLabel: item.isDerLabel
      }
      if (!this.derivedTagData.tagList.length) this.derivedTagData.logicalOperation = 'and'
      this.derivedTagData.tagList.push(arg)
    },
    copyDrag(event, item, index = -1, index2 = -1, index3 = -1) {
      if (!item.tagId) return
      event.dataTransfer.setData('tagId', item.tagId)
      event.dataTransfer.setData('tagNm', item.tagNm)
      event.dataTransfer.setData('valueType', item.valueType)
      event.dataTransfer.setData('valueTypeCode', item.valueTypeCode)
      event.dataTransfer.setData('tagCode', item.tagCode)
      event.dataTransfer.setData('operationType', item.operationType)
      event.dataTransfer.setData('operationValue', JSON.stringify(item.operationValue))
      event.dataTransfer.setData('enums', JSON.stringify(item.enums))
      event.dataTransfer.setData('labTbl', item.labTbl) // 表名
      event.dataTransfer.setData('labFldMap', item.labFldMap) // 字段名
      event.dataTransfer.setData('dictDatabaseType', item.dictDatabaseType) // 数据库类型
      event.dataTransfer.setData('config', JSON.stringify(Object.assign({}, item, { index, index2, index3 })))
      event.dataTransfer.setData('clientY', event.clientY)
      event.dataTransfer.setData('isDerLabel', item.isDerLabel || '0')
    },
    allowDrag(event) {
      event.preventDefault()
    },
    copyDrop(event) {
      // 判断拖动的高度小于50则不改变
      if (event.dataTransfer.getData('clientY')) {
        let clientY = event.dataTransfer.getData('clientY')
        if (Math.abs(event.clientY - clientY) < 50) return
      }
      let isConfig = event.dataTransfer.getData('config')
      event.preventDefault()
      let tagId = event.dataTransfer.getData('tagId')
      if (!tagId) return
      let content = this.derivedTagData.tagList
      let tagNm = event.dataTransfer.getData('tagNm')
      let valueType = event.dataTransfer.getData('valueType')
      let tagCode = event.dataTransfer.getData('tagCode')
      let operationType = event.dataTransfer.getData('operationType')
      let operationValue = event.dataTransfer.getData('operationValue').length
        ? JSON.parse(event.dataTransfer.getData('operationValue'))
        : event.dataTransfer.getData('operationValue')
      let valueTypeCode = event.dataTransfer.getData('valueTypeCode')
      let enums = JSON.parse(event.dataTransfer.getData('enums'))
      let labTbl = event.dataTransfer.getData('labTbl')
      let labFldMap = event.dataTransfer.getData('labFldMap')
      let dictDatabaseType = event.dataTransfer.getData('dictDatabaseType')
      let isDerLabel = event.dataTransfer.getData('isDerLabel')
      let arg = {
        tagId,
        tagNm,
        valueType,
        tagCode,
        valueTypeCode,
        enums,
        labTbl,
        labFldMap,
        dictDatabaseType,
        operationType,
        operationValue,
        isDerLabel
      }
      if (
        this.derivedTagData.tagList.length < 2 ||
        event.target.className.split(' ').find(item => item === 'list-wrap') ||
        event.target.className.split(' ').find(item => item === 'sub-title')
      ) {
        if (!this.derivedTagData.tagList.length) this.derivedTagData.logicalOperation = 'and'
        this.derivedTagData.tagList.push(arg)
      } else {
        let nodes = []
        let target = event.target
        if (target.className.includes('el-input__inner')) {
          // 拖到逻辑条件处，直接添加
          const targetLevel = target.parentNode.parentNode.getAttribute('level')
          if (!targetLevel) this.derivedTagData.tagList.push(arg)
          else if (targetLevel.indexOf('-') > -1) {
            // 第三层
            const level1 = targetLevel.split('-')[0]
            const level2 = targetLevel.split('-')[1]
            this.derivedTagData.tagList[level1].tagList[level2].tagList.push(arg)
          } else {
            this.derivedTagData.tagList[targetLevel].tagList.push(arg)
          }
        } else {
          while (target.className !== 'ul') {
            nodes.push(target)
            target = target.parentNode
          }
          const li = nodes.find(item => item.className === 'list-item')
          if (!li) return
          const targetLevel = parseInt(li.getAttribute('level'))
          const targetId = li.getAttribute('tagId')
          if (targetLevel === 1) {
            // 拖到第一层，一起掉到第二层
            const index = Number(li.getAttribute('index'))
            for (let i = 0; i < content.length; i++) {
              if (content[i].tagId === targetId && i === index) {
                const old_content = content[i]
                this.$set(content, i, {
                  logicalOperation: 'and',
                  tagList: [old_content, arg]
                })
              }
            }
          } else if (targetLevel === 2) {
            // 拖到第二层，一起掉到第三层
            const index = li.getAttribute('index')
            const index1 = index.split('-')[0]
            const index2 = index.split('-')[1]
            const old_content = content[index1].tagList[index2]
            this.$set(content[index1].tagList, index2, {
              logicalOperation: 'and',
              tagList: [old_content, arg]
            })
          } else {
            const index = li.getAttribute('index')
            const index1 = index.split('-')[0]
            const index2 = index.split('-')[1]
            const index3 = index.split('-')[2]
            content[index1].tagList[index2].tagList.splice(index3 + 1, 0, arg)
          }
        }
      }
      if (isConfig) {
        // 右侧拖动，删除原来的数据源
        let config = JSON.parse(isConfig)
        this.deleteItem(config.index, config.index2, config.index3)
        // 将子元素插入到原来图层
        if (config.derivedTag && config.derivedTag.tagList.length) {
          content.splice(config.index, 0, ...config.derivedTag.tagList)
        }
      }
      this.$forceUpdate()
    },
    deleteItem(index = -1, index2 = -1, index3 = -1) {
      if (index3 >= 0) {
        this.derivedTagData.tagList[index].tagList[index2].tagList.splice(index3, 1)
        // 如果只剩一条，则提升到第二层
        if (this.derivedTagData.tagList[index].tagList[index2].tagList.length < 2) {
          const content = this.derivedTagData.tagList[index].tagList[index2].tagList[0]
          this.derivedTagData.tagList[index].tagList.splice(index2, 1, content)
        }
      } else {
        if (index2 >= 0) {
          this.derivedTagData.tagList[index].tagList.splice(index2, 1)
          // 如果只剩一条，则提升到第一层
          if (this.derivedTagData.tagList[index].tagList.length < 2) {
            const content = this.derivedTagData.tagList[index].tagList[0]
            this.derivedTagData.tagList.splice(index, 1, content)
          }
        } else {
          this.derivedTagData.tagList.splice(index, 1)
          // 如果只剩一条合并数据，则提升到第一层
          if (this.derivedTagData.tagList.length && this.derivedTagData.tagList.length < 2) {
            const content = this.derivedTagData.tagList[0]
            if (!content.tagId) {
              this.derivedTagData.logicalOperation = content.logicalOperation
              this.derivedTagData.tagList = content.tagList
            }
          }
        }
      }
    }
  }
}
</script>

<style lang="scss">
@import '@/views/modules/factory/factory.scss';
.similar-logic {
  position: relative;
  .logic-handler {
    position: absolute;
    top: 10px;
    right: 20px;
  }
  .logic-title {
    .el-input__inner {
      font-size: 17px;
      font-weight: bold;
      border: 0;
      padding-left: 40px;
    }
    .el-input__prefix {
      font-size: 20px;
      color: $theme-color;
    }
  }
  .logic-info {
    padding: 50px 0;
    margin-left: -50px;
    color: #666;
    background-color: #f6f7f8;
    text-align: center;
    i {
      margin-right: 5px;
    }
  }
}
</style>
